/*
 * @Author: Sian Li lisian_magic@163.com
 * @Date: 2024-07-01 16:06:28
 * @LastEditors: Sian Li lisian_magic@163.com
 * @LastEditTime: 2024-07-05 15:17:38
 * @FilePath: /hudar/src/hudar/src/RadarClass/Camera/Camera.cpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置
 * 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "Camera.h"

HKCam::HKCam() {
    // ch:初始化SDK | en:Initialize SDK
    nRet = MV_CC_Initialize();
    if (MV_OK != nRet) {
        // printf("Initialize SDK fail! nRet [0x%x]\n", nRet);
        this->logger->info("Initialize SDK fail! nRet [0x]\n");
        this->logger->flush();
    }

    MV_CC_DEVICE_INFO_LIST stDeviceList;
    memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));

    // 枚举设备
    // enum device
    nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_EnumDevices fail! nRet []\n");
    }
    if (stDeviceList.nDeviceNum > 0) {
        for (int i = 0; i < stDeviceList.nDeviceNum; i++) {
            MV_CC_DEVICE_INFO *pDeviceInfo = stDeviceList.pDeviceInfo[i];
            if (NULL == pDeviceInfo) {
            }
        }
    } else {
        this->logger->info("Find No Devices!\n");
    }
    // 选择设备并创建句柄
    // select device and create handle
    nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[0]);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_CreateHandle fail! nRet [%x]\n");
    }
    // 打开设备
    // open device
    nRet = MV_CC_OpenDevice(handle);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_OpenDevice fail! nRet [%x]\n");
    }
    // 设置参数
    nRet = MV_CC_SetFloatValue(handle, "ExposureTime", 7000);
    if (MV_OK == nRet) {
        this->logger->info("set exposure time OK!\n\n");
    } else {
        this->logger->info("set exposure time failed! nRet [%x]\n\n");
    }
    if (MV_OK == nRet) {
        this->logger->info("set PixelFormat  OK!\n\n");
    } else {
        this->logger->info("set PixelFormat  failed! nRet [%x]\n\n");
    }
    nRet = MV_CC_SetFloatValue(handle, "Gain", 15);
    if (MV_OK == nRet) {
        this->logger->info("set Gain OK!\n\n");
    } else {
        this->logger->info("set Gain failed! nRet [%x]\n\n");
    }
    // 设置触发模式为off
    // set trigger mode as off
    nRet = MV_CC_SetEnumValue(handle, "TriggerMode", 0);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_SetTriggerMode fail! nRet [%x]\n");
    }

    // 开始取流
    // start grab image
    nRet = MV_CC_StartGrabbing(handle);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_StartGrabbing fail! nRet [%x]\n");
    }

    // ch:获取数据包大小 | en:Get payload size
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    nRet = MV_CC_GetIntValue(handle, "PayloadSize", &stParam);
    if (MV_OK != nRet) {
        this->logger->info("Get PayloadSize fail! nRet [0x%x]\n");
    }
    memset(&stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
    pData = (unsigned char *)malloc(sizeof(unsigned char) * stParam.nCurValue);
    nDataSize = stParam.nCurValue;

    this->logger->info("Camera OK");
    this->logger->flush();
}

HKCam::~HKCam() {
    free(pData);
    pData = NULL;
    // 停止取流
    // end grab image
    nRet = MV_CC_StopGrabbing(handle);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_StopGrabbing fail! nRet [%x]\n");
    }

    // 关闭设备
    // close device
    nRet = MV_CC_CloseDevice(handle);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_CloseDevice fail! nRet [%x]\n");
    }

    // 销毁句柄
    // destroy handle
    nRet = MV_CC_DestroyHandle(handle);
    if (MV_OK != nRet) {
        this->logger->info("MV_CC_DestroyHandle fail! nRet [%x]\n");
    }
    if (handle != NULL) {
        MV_CC_DestroyHandle(handle);
        handle = NULL;
    }

    // ch:反初始化SDK | en:Finalize SDK
    MV_CC_Finalize();
}

cv::Mat HKCam::getFrame() {
    cv::Mat res;
    nRet =
        MV_CC_GetOneFrameTimeout(handle, pData, nDataSize, &stImageInfo, 1000);
    if (nRet != MV_OK) {
        printf("No data[%x]\n", nRet);
        return res;
    }
    res = cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC1, pData);
    cv::Mat bgr = cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC3);
    // 最后转换成BGR格式
    cv::cvtColor(res, bgr, cv::COLOR_BayerGB2RGB);
    return bgr;
}
